package com.boarsoft.boar.sys.action;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.SecureRandom;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.boarsoft.bean.ReplyInfo;
import com.boarsoft.boar.auth.TokenAuth;
import com.boarsoft.boar.common.Constants;
import com.boarsoft.boar.common.Logon;
import com.boarsoft.boar.sys.SysPowerBiz;
import com.boarsoft.common.Authorized;
import com.boarsoft.common.Util;

@RestController
@RequestMapping("/sys/power")
public class SysPowerAction {
	private static final Logger log = LoggerFactory.getLogger(SysPowerAction.class);
	
	@Autowired
	private SysPowerBiz sysPowerBiz;
	@Autowired
	private TokenAuth tokenAuth;

	/**
	 * 检查TOKEN有效性，需要注入logon，但不需要登录，所以code为空
	 */
	@RequestMapping("/verify.do")
	@Authorized(code = "")
	public String verify(String code, String token, String logon) {
		if (Util.strIsEmpty(token)) {
			return "false";
		}
		if (logon == null) {
			return "false";
		}
		String uid = sysPowerBiz.checkToken(token);// 此方法返回用户ID
		if (Util.strIsEmpty(uid)) {
			return "false";
		}
		return sysPowerBiz.check(uid, code) ? "true" : "false";
	}

	/**
	 * 检查用户是否已登录
	 * @return 
	 */
	@RequestMapping("/check.do")
	@Authorized
	public ReplyInfo<Object> check(@CookieValue String token) {
		try {
			ReplyInfo<Object> ri = tokenAuth.check(token);
			if (ri.isSuccess()) {
				Logon lg = (Logon) ri.getData();
				lg.setToken(token);
				return new ReplyInfo<Object>(true, lg);
			}
			return Constants.REPLY_INFO_NOTFOUND;
		} catch (Exception e) {
			log.error("Error on authorize token {}", token, e);
			return Constants.REPLY_ERROR_INTERNAL;
		}
	}

	/**
	 * TODO 登录三次不成功后，需输验证码，不需要身份认证
	 * 
	 * @return
	 * @throws IOException
	 * @throws Exception
	 */
	@RequestMapping(value = "/verifyCode.do", produces = MediaType.IMAGE_JPEG_VALUE)
	public byte[] verifyCode(HttpSession session) throws IOException {
		// 在内存中创建图象
		int width = 65, height = 20;
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		// 获取图形上下文
		Graphics g = image.getGraphics();
		// 生成随机类
		Random random = new SecureRandom();
		// 设定背景色
		g.setColor(getRandColor(200, 250));
		g.fillRect(0, 0, width, height);
		// 设定字体
		g.setFont(new Font("Times New Roman", Font.PLAIN, 12));
		// 随机产生155条干扰线，使图象中的认证码不易被其它程序探测到
		g.setColor(getRandColor(160, 200));
		for (int i = 0; i < 155; i++) {
			int x = random.nextInt(width);
			int y = random.nextInt(height);
			int xl = random.nextInt(12);
			int yl = random.nextInt(12);
			g.drawLine(x, y, x + xl, y + yl);
		}
		// 取随机产生的认证码(5位数字)
		String sRand = "";
		for (int i = 0; i < 5; i++) {
			String rand = String.valueOf(random.nextInt(10));
			sRand += rand;
			// 将认证码显示到图象中
			g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
			// 调用函数出来的颜色相同，可能是因为种子太接近，所以只能直接生成
			g.drawString(rand, 13 * i + 6, 16);
		}
		// 将认证码存入SESSION
		session.setAttribute("vc", sRand);
		// 图象生效
		g.dispose();
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);
		ImageIO.write(image, "JPEG", imageOut);
		imageOut.close();
		return output.toByteArray();
	}

	// 给定范围获得随机颜色
	private Color getRandColor(int fc, int bc) {
		Random random = new SecureRandom();
		if (fc > 255)
			fc = 255;
		if (bc > 255)
			bc = 255;
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}
}